package com.fh.modules.dbms.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fh.common.util.DateUtils;
import com.fh.common.util.StringUtils;
import com.fh.common.web.impl.AbstractServiceImpl;
import com.fh.db.DbPackage;
import com.fh.db.DbPackageBody;
import com.fh.db.DbPackageDeclare;
import com.fh.modules.dbms.entity.DbmsPackage;
import com.fh.modules.dbms.entity.DbmsPackageBody;
import com.fh.modules.dbms.entity.DbmsPackageDeclare;
import com.fh.modules.dbms.mapper.DbmsPackageMapper;
import com.fh.modules.dbms.model.PackageCompareResult;
import com.fh.modules.dbms.service.IDbmsPackageBodyService;
import com.fh.modules.dbms.service.IDbmsPackageDeclareService;
import com.fh.modules.dbms.service.IDbmsPackageService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author qiujunda
 * @Date 23/07/2020
 * @Description
 */
@Service
public class DbmsPackageServiceImpl extends AbstractServiceImpl<DbmsPackageMapper, DbmsPackage> implements IDbmsPackageService {
    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
    @Autowired
    private IDbmsPackageDeclareService dbmsPackageDeclareService;
    @Autowired
    private IDbmsPackageBodyService dbmsPackageBodyService;

    @Override
    @Transactional
    public DbmsPackage addOrUpdateDbmsPackage(DbPackage dbPackage, Long sourceId, String collectSid) {
        DbmsPackage dbmsPackageOld=queryDbmsPackage(sourceId,dbPackage.getPackageName());
        //是否需要修改包信息
        boolean updatePackageOther=false;
        //是否修改包申明
        boolean updatePackageDelare=false;
        //是否修改包体
        boolean updatePackageBody=false;
        if(dbmsPackageOld==null){
            dbmsPackageOld=new DbmsPackage();
            updatePackageOther=true;
        }else if((updatePackageDelare=!DateUtils.compareDate(dbPackage.getPackageLastDdlTime(),dbmsPackageOld.getPackageLastDdlTime()))
        ||(updatePackageBody=!DateUtils.compareDate(dbPackage.getBodyLastDdlTime(),dbmsPackageOld.getBodyLastDdlTime()))){
            //根据表的最近更新时间判断是否需要更新索引，字段，触发器等信息
            updatePackageOther=true;
        }
        BeanUtils.copyProperties(dbPackage,dbmsPackageOld);
        dbmsPackageOld.setSourceId(sourceId);
        dbmsPackageOld.setCollectSid(collectSid);
        if(updatePackageOther){
            List<DbPackageDeclare> dbPackageDeclareList=dbPackage.getDbPackageDeclare();
            List<DbPackageBody> dbPackageBodyList=dbPackage.getDbPackageBody();
            dbmsPackageOld.setBodyLines(dbPackageBodyList.size());
            dbmsPackageOld.setDeclareLines(dbPackageDeclareList.size());
            this.saveOrUpdate(dbmsPackageOld);
            long dbmsPackageId=dbmsPackageOld.getId();
            if(updatePackageDelare){
                dbmsPackageDeclareService.deleteByPackageId(dbmsPackageId);
                for(DbPackageDeclare dbPackageDeclare:dbPackageDeclareList){
                    taskExecutor.execute(()->{
                        DbmsPackageDeclare dbmsPackageDeclare=new DbmsPackageDeclare();
                        BeanUtils.copyProperties(dbPackageDeclare,dbmsPackageDeclare);
                        dbmsPackageDeclare.setPackageId(dbmsPackageId);
                        dbmsPackageDeclareService.save(dbmsPackageDeclare);
                    });

                }
            }
            if(updatePackageBody){
                dbmsPackageBodyService.deleteByPackageId(dbmsPackageId);
                for(DbPackageBody dbPackageBody:dbPackageBodyList){
                    taskExecutor.execute(()->{
                        DbmsPackageBody dbmsPackageBody=new DbmsPackageBody();
                        BeanUtils.copyProperties(dbPackageBody,dbmsPackageBody);
                        dbmsPackageBody.setPackageId(dbmsPackageId);
                        dbmsPackageBodyService.save(dbmsPackageBody);
                    });
                }
            }
        }else{
            this.updateById(dbmsPackageOld);
        }
        return dbmsPackageOld;
    }

    @Override
    public List<PackageCompareResult> comparePackage(Long sourceId1, Long sourceId2, String packageName, Integer diff) {
        List<PackageCompareResult> packageCompareResults=new ArrayList<>();
        List<DbmsPackage> dbmsPackageList=this.queryDbmsPackages(sourceId1,packageName);
        for(DbmsPackage dbmsPackage:dbmsPackageList){
            boolean delareResult,bodyResult,result;
            DbmsPackage dbmsPackageDes=this.queryDbmsPackage(sourceId2,dbmsPackage.getPackageName());
            PackageCompareResult packageCompareResult;
            if(dbmsPackageDes==null){
                packageCompareResult=new PackageCompareResult(dbmsPackage.getPackageName(),"");
            }else{
                packageCompareResult=new PackageCompareResult(dbmsPackage.getPackageName(),dbmsPackageDes.getPackageName());
                delareResult=(dbmsPackage.getDeclareLines()==dbmsPackageDes.getDeclareLines());
                bodyResult=(dbmsPackage.getBodyLines()==dbmsPackageDes.getBodyLines());
                if(delareResult){
                    delareResult=dbmsPackageDeclareService.comparePackageDelare(dbmsPackage.getId(),dbmsPackageDes.getId());
                }
                if(bodyResult){
                    bodyResult=dbmsPackageBodyService.comparePackageBody(dbmsPackage.getId(),dbmsPackageDes.getId());
                }
                result=(delareResult&&bodyResult);
                packageCompareResult.setDeclareResult(delareResult);
                packageCompareResult.setBodyResult(bodyResult);
                packageCompareResult.setResult(result);
                packageCompareResult.initLastDdlTime(dbmsPackage,dbmsPackageDes);
            }
            if(diff==null||(diff==1&&packageCompareResult.isResult())||(diff==0&&!packageCompareResult.isResult())){
                packageCompareResults.add(packageCompareResult);
            }

        }
        return packageCompareResults;
    }

    @Override
    public DbmsPackage queryDbmsPackage(Long sourceId, String packageName){
        QueryWrapper<DbmsPackage> queryWrapper = new QueryWrapper<DbmsPackage>();
        queryWrapper.eq("source_id", sourceId).eq("package_name", packageName).eq("del_flag",0);
        return this.getOne(queryWrapper);
    }

    public List<DbmsPackage> queryDbmsPackages(Long sourceId,String packageName){
        QueryWrapper<DbmsPackage> queryWrapper = new QueryWrapper<DbmsPackage>();
        queryWrapper.eq("source_id", sourceId).eq("del_flag",0);
        if(StringUtils.isNotEmpty(packageName)){
            queryWrapper.eq("package_name", packageName);
        }
        queryWrapper.orderByDesc("body_last_ddl_time");
        return this.list(queryWrapper);
    }
}
